package com.bill99.rpc.registry;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import com.bill99.rpc.common.Constants;
import com.bill99.rpc.common.util.UrlUtils;

/**
 * @author sheng.zhang
 * 
 */
public class BaseUrl implements Serializable {

	private static final long serialVersionUID = 1L;

	// 协议
	protected String protocol;

	// 主机
	protected String host;

	// 端口
	protected int port;

	// 应用路径
	protected String path;

	// 参数
	protected Map<String, String> parameters;

	public BaseUrl() {
		this.protocol = null;
		this.host = null;
		this.port = 0;
		this.path = null;
		this.parameters = null;
	}

	public BaseUrl(String protocol, String host, int port) {
		this(protocol, host, port, null);
	}

	public BaseUrl(String protocol, String host, int port, String path) {
		this(protocol, host, port, path, null);
	}

	public BaseUrl(String protocol, String host, int port, String path,
			Map<String, String> parameters) {
		this.protocol = protocol;
		this.host = host;
		this.port = (port < 0 ? 0 : port);
		// trim the beginning "/"
		while (path != null && path.startsWith("/")) {
			path = path.substring(1);
		}
		this.path = path;
		if (parameters == null) {
			parameters = new HashMap<String, String>();
		} else {
			parameters = new HashMap<String, String>(parameters);
		}
		this.parameters = Collections.unmodifiableMap(parameters);
	}

	public String getProtocol() {
		return protocol;
	}

	public String getHost() {
		return host;
	}

	public int getPort() {
		return port;
	}

	public String getPath() {
		return path;
	}

	public String getAddress() {
		return port <= 0 ? host : host + ":" + port;
	}

	public Map<String, String> getParameters() {
		return parameters;
	}

	public String getParameterAndDecoded(String key) {
		return getParameterAndDecoded(key, null);
	}

	public String getParameterAndDecoded(String key, String defaultValue) {
		return UrlUtils.decode(getParameter(key, defaultValue));
	}

	public String getParameter(String key) {
		String value = parameters.get(key);
		return value;
	}

	public String getParameter(String key, String defaultValue) {
		String value = getParameter(key);
		if (value == null || value.length() == 0) {
			return defaultValue;
		}
		return value;
	}

	public double getParameter(String key, double defaultValue) {
		String value = getParameter(key);
		if (value == null || value.length() == 0) {
			return defaultValue;
		}
		double d = Double.parseDouble(value);
		return d;
	}

	public long getParameter(String key, long defaultValue) {
		String value = getParameter(key);
		if (value == null || value.length() == 0) {
			return defaultValue;
		}
		long l = Long.parseLong(value);
		return l;
	}

	public int getParameter(String key, int defaultValue) {
		String value = getParameter(key);
		if (value == null || value.length() == 0) {
			return defaultValue;
		}
		int i = Integer.parseInt(value);
		return i;
	}

	public String getServiceInterface() {
		return getParameter(Constants.INTERFACE_KEY);
	}

	protected void buildParameters(StringBuilder buf) {
		if (getParameters() != null && getParameters().size() > 0) {
			boolean first = true;
			for (Map.Entry<String, String> entry : new TreeMap<String, String>(
					getParameters()).entrySet()) {
				if (entry.getKey() != null
						&& entry.getKey().trim().length() > 0) {
					if (first) {
						buf.append("?");
						first = false;
					} else {
						buf.append("&");
					}
					buf.append(entry.getKey());
					buf.append("=");
					buf.append(entry.getValue() == null ? "" : entry.getValue()
							.trim());
				}
			}
		}
	}

}
